//记录Promise的三种状态
const PENDING='pending';
const FULFILLED='fulfilled';
const REJECTED='rejected';

/**
 * 运行一个微队列，把传递的函数放到微队列中
 * @param {Function} callback 
 */
function runMicroTask(callback){
    //判断是node环境
    if(process &&process.nextTick){
        process.nextTick(callback)
    }else if(MutationObserver){//判断是浏览器环境
        new MutationObserver(callback)
    }else{
        setTimeout(callback,0);
    }
}
/**
 * 判断一个数据是否是promise对象
 * @param {any} obj 
 * @returns 
 */
function isPromise(obj){
    return !!(obj && typeof obj==='object' && typeof obj.then ==='function'); 
}

class MyPromise{
    /**
     * 创建一个Promise
     * @param {Function} executor 任务执行器，立即执行
     */
    constructor(executor){
        this._state=PENDING;//状态
        this._value=undefined;//数据
        this._handlers=[];//处理函数形成的队列
        try{
            executor(this._resolve.bind(this),this._reject.bind(this))
        }catch(error){
            this._reject(error)
        }
    }

    _changeState(newState,value){
        if(this._state!==PENDING){
            return
        }
        this._state=newState;
        this._value=value;
        this._runHandlers();//状态改变，执行队列
    }

   /**
    *  向任务队列里添加一个函数
    * @param {Function} executor    函数
    * @param {String} state         状态，标志该函数在成功状态或者失败状态下执行
    * @param {Function} resolve     让then函数返回成功 
    * @param {Function} reject      让then函数返回失败
    */
    _pushHandler(executor,state,resolve,reject){
        this._handlers.push({
            executor,
            state,
            resolve,
            reject,
        });
    }

    /**
     * 运行队列
     */
    _runHandlers(){
        console.log(this._state);
        if(this._state===PENDING){
            //目前任务仍在挂起
            return;
        }
        console.log("处理了函数个数",this._handlers.length)
        console.log(this._handlers)
        
        while(this._handlers[0]){
            const hander=this._handlers[0];
            this._runCurHandler(hander);
            this._handlers.shift()
        }
        
    }

    /**
     * 运行当前队列函数
     *  @param {Function} hander 
     */
    _runCurHandler({executor,state,resolve,reject}){
        runMicroTask(()=>{
            if(this._state!==state){
                //状态不一致不处理
                return;
            }
            console.log(this._state);
            console.log(executor);
            //传递后续并不是一个函数的情况
            if(typeof executor!=='function'){
                this._state===FULFILLED?resolve(this._value):reject(this._value);
                return;
            }
            try{
                const result=executor(this._value);
                //还要考虑一个问题，返回的结果是不是Promise
                if(isPromise(result)){
                    result.then(resolve,reject)
                }else{
                    resolve(result);
                }
            }catch(error){
                reject(error)
            }
        })
    }

    /**
     * 
     * @param {Function} onFulfilled 
     * @param {Function} onRejected 
     */
    then(onFulfilled,onRejected){
        return new MyPromise((resolve,reject)=>{
            this._pushHandler(onFulfilled,FULFILLED,resolve,reject);
            this._pushHandler(onRejected,REJECTED,resolve,reject);
            //刚加入队列还没改变状态时也要执行一下队列
            this._runHandlers();
        })
    
    }

    /**
     * 标记当前任务完成
     * @param {any} data 当前任务完成返回数据 
     */
    _resolve(data){
        this._changeState(FULFILLED,data);
    }

    /**
     * 标记当前任务失败
     * @param {any} reason 当前任务失败返回数据 
     */
    _reject(reason){
        this._changeState(REJECTED,reason)
    }

}

const pro=new MyPromise((resolve,reject)=>{
    // throw new Error(123)
    setTimeout(()=>{
        resolve(123);
    })
})
const pro2=pro.then((data)=>{
    // throw 123456;
    // console.log(11111)
    return new Promise((resolve,reject)=>{
        reject(1111);
    })
    return 456
})
setTimeout(()=>{
    console.log(pro)
    console.log(pro2)
},200)

